# -*- coding: utf-8 -*-

import random

"""
X = (x1, x2, ..., xn)
Y = (y1, y2, ..., yn)
xi与yi进行比较, 分三种情况:
  (1) xi = yi, 对应的权重值为  zi = 1  （完全相等)
  (2) |xi - yi|/|xi| >= 1; 则 zi = 0   (相对误差大于100%)
  (3) |xi - yi|/|xi| < 1,  则 zi = |xi - yi|/|xi| (相对误差小于100%)
"""
# 模糊杰卡德适应值函数
# 参数:
#   X -- 真值
#   Y -- 染色体串
def fitness(X, Y):
    # 杰卡德相似映射
    def jaccard(x):
        if x < 1e-3:
            return 1
        elif x >= 1.0:
            return 0
        else:
            return x

    # 相对误差
    def re_tol(x, y):
        return abs(x - y) / (abs(x) + 1e-6)

    # 相对误差
    D = [re_tol(x, y) for x, y in zip(X, Y)]
    # 模糊杰卡德系数
    # map是python内置的标准函数, 应用jaccard函数对数组 D中的每个数据进行计算, 得到一个新的数组 J
    J = list(map(jaccard, D))
    print("X\tY\t相对误差\t杰卡德系数")
    for i in range(len(X)):
        print("%.4f\t%.4f\t%7.2f%%\t%10.2f" % (X[i], Y[i], D[i] * 100, J[i]))
    # 求和
    s = 0
    for x in J:
        s += x
    print("[合计]杰卡德适应值:", s)
    return s


def main():
    # 随机生成一组数据(N个)
    N = 10
    X = [random.random() for i in range(N)]
    Y = [random.random() for i in range(N)]
    # print("X=", X)
    # print("Y=", Y)
    # print("X和X:", fitness(X, X))
    # print("Y和Y:", fitness(Y, Y))
    print("X和Y:", fitness(X, Y))
    print("\n====================================================\n")
    print("Y和X:", fitness(Y, X))


if __name__ == "__main__":
    main()
